home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_gnu / adainc / a-stwiun.adb < prev    next >
Text File  |  1996-01-30  |  17KB  |  537 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT RUNTIME COMPONENTS                          --
  4. --                                                                          --
  5. --           A D A . S T R I N G S . W I D E _ U N B O U N D E D            --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.5 $                              --
  10. --                                                                          --
  11. --           Copyright (c) 1992,1993,1994 NYU, All Rights Reserved          --
  12. --                                                                          --
  13. -- The GNAT library is free software; you can redistribute it and/or modify --
  14. -- it under terms of the GNU Library General Public License as published by --
  15. -- the Free Software  Foundation; either version 2, or (at your option) any --
  16. -- later version.  The GNAT library is distributed in the hope that it will --
  17. -- be useful, but WITHOUT ANY WARRANTY;  without even  the implied warranty --
  18. -- of MERCHANTABILITY  or  FITNESS FOR  A PARTICULAR PURPOSE.  See the  GNU --
  19. -- Library  General  Public  License for  more  details.  You  should  have --
  20. -- received  a copy of the GNU  Library  General Public License  along with --
  21. -- the GNAT library;  see the file  COPYING.LIB.  If not, write to the Free --
  22. -- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        --
  23. --                                                                          --
  24. ------------------------------------------------------------------------------
  25.  
  26. --  Note: This code is derived from the ADAR.CSH public domain Ada 83
  27. --  version of Strings.Bounded of the Appendix C string handling packages.
  28.  
  29.  
  30. with Ada.Strings.Wide_Fixed;
  31. with Ada.Strings.Wide_Search;
  32. with Unchecked_Deallocation;
  33.  
  34. package body Ada.Strings.Wide_Unbounded is
  35.  
  36.    -----------------------
  37.    -- Local Subprograms --
  38.    -----------------------
  39.  
  40.    procedure Free (Handle : in out Unbounded_Wide_String);
  41.    --  Free an unbounded string using unchecked deallocation. This is used
  42.    --  only internally to this package by those routines which must be sure
  43.    --  to free a string before reassigning it. This is a temporary kludge
  44.    --  to make up for the fact that we do not have finalization yet! ???
  45.  
  46.    ---------
  47.    -- "=" --
  48.    ---------
  49.  
  50.    function "="  (Left, Right : in Unbounded_Wide_String) return Boolean is
  51.    begin
  52.       return Left.Reference.all = Right.Reference.all;
  53.    end "=";
  54.  
  55.    ---------
  56.    -- "<" --
  57.    ---------
  58.  
  59.    function "<"  (Left, Right : in Unbounded_Wide_String) return Boolean is
  60.    begin
  61.       return Left.Reference.all < Right.Reference.all;
  62.    end "<";
  63.  
  64.    ----------
  65.    -- "<=" --
  66.    ----------
  67.  
  68.    function "<=" (Left, Right : in Unbounded_Wide_String) return Boolean is
  69.    begin
  70.       return Left.Reference.all <= Right.Reference.all;
  71.    end "<=";
  72.  
  73.    ---------
  74.    -- ">" --
  75.    ---------
  76.  
  77.    function ">"  (Left, Right : in Unbounded_Wide_String) return Boolean is
  78.    begin
  79.       return Left.Reference.all > Right.Reference.all;
  80.    end ">";
  81.  
  82.    ----------
  83.    -- ">=" --
  84.    ----------
  85.  
  86.    function ">=" (Left, Right : in Unbounded_Wide_String) return Boolean is
  87.    begin
  88.       return Left.Reference.all >= Right.Reference.all;
  89.    end ">=";
  90.  
  91.    ---------
  92.    -- "*" --
  93.    ---------
  94.  
  95.    function "*" (Left : in Natural; Right : in Wide_Character)
  96.      return Unbounded_Wide_String
  97.    is
  98.       Result : Unbounded_Wide_String :=
  99.                  (Reference => new Wide_String (1 .. Left));
  100.  
  101.    begin
  102.       Result.Reference.all := (1 .. Left => Right);
  103.       return Result;
  104.    end "*";
  105.  
  106.    function "*" (Left : in Natural; Right : in Wide_String)
  107.      return Unbounded_Wide_String
  108.    is
  109.       Result : Unbounded_Wide_String :=
  110.          (Reference => new Wide_String (1 .. Left * Right'Length));
  111.  
  112.    begin
  113.       for I in 1 .. Left loop
  114.          Result.Reference.all
  115.            (Right'Length * I - Right'Length + 1 .. Right'Length * I) := Right;
  116.       end loop;
  117.  
  118.       return Result;
  119.    end "*";
  120.  
  121.    function "*" (Left : in Natural; Right : in Unbounded_Wide_String)
  122.      return Unbounded_Wide_String
  123.    is
  124.       R_Length : constant Integer := Right.Reference.all'Length;
  125.       Result   : Unbounded_Wide_String :=
  126.         (Reference =>
  127.           new Wide_String (1 .. Left * Right.Reference.all'Length));
  128.  
  129.    begin
  130.       for I in 1 .. Left loop
  131.          Result.Reference.all (R_Length * I - R_Length + 1 .. R_Length * I) :=
  132.            Right.Reference.all;
  133.       end loop;
  134.  
  135.       return Result;
  136.    end "*";
  137.  
  138.    ---------
  139.    -- "&" --
  140.    ---------
  141.  
  142.    function "&" (Left, Right : in Unbounded_Wide_String)
  143.      return Unbounded_Wide_String
  144.    is
  145.       L_Length : constant Integer := Left.Reference.all'Length;
  146.       R_Length : constant Integer := Right.Reference.all'Length;
  147.       Length   : constant Integer :=  L_Length + R_Length;
  148.       Result   : Unbounded_Wide_String :=
  149.                    (Reference => new Wide_String (1 .. Length));
  150.  
  151.    begin
  152.       Result.Reference.all (1 .. L_Length)          := Left.Reference.all;
  153.       Result.Reference.all (L_Length + 1 .. Length) := Right.Reference.all;
  154.       return Result;
  155.    end "&";
  156.  
  157.    function "&" (Left : in Unbounded_Wide_String; Right : Wide_String)
  158.      return Unbounded_Wide_String
  159.    is
  160.       L_Length : constant Integer := Left.Reference.all'Length;
  161.       Length   : constant Integer := L_Length +  Right'Length;
  162.       Result   : Unbounded_Wide_String :=
  163.                    (Reference => new Wide_String (1 .. Length));
  164.  
  165.    begin
  166.       Result.Reference.all (1 .. L_Length)          := Left.Reference.all;
  167.       Result.Reference.all (L_Length + 1 .. Length) := Right;
  168.       return Result;
  169.    end "&";
  170.  
  171.    function "&" (Left : in Wide_String; Right : Unbounded_Wide_String)
  172.      return Unbounded_Wide_String
  173.    is
  174.       R_Length : constant Integer := Right.Reference.all'Length;
  175.       Length   : constant Integer := Left'Length + R_Length;
  176.       Result   : Unbounded_Wide_String :=
  177.                    (Reference => new Wide_String (1 .. Length));
  178.  
  179.    begin
  180.       Result.Reference.all (1 .. Left'Length)          := Left;
  181.       Result.Reference.all (Left'Length + 1 .. Length) := Right.Reference.all;
  182.       return Result;
  183.    end "&";
  184.  
  185.    function "&" (Left : in Unbounded_Wide_String; Right : Wide_Character)
  186.      return Unbounded_Wide_String
  187.    is
  188.       Length : constant Integer := Left.Reference.all'Length + 1;
  189.       Result : Unbounded_Wide_String :=
  190.                  (Reference => new Wide_String (1 .. Length));
  191.  
  192.    begin
  193.       Result.Reference.all (1 .. Length - 1) := Left.Reference.all;
  194.       Result.Reference.all (Length)          := Right;
  195.       return Result;
  196.    end "&";
  197.  
  198.    function "&" (Left : in Wide_Character; Right : Unbounded_Wide_String)
  199.      return Unbounded_Wide_String
  200.    is
  201.       Length : constant Integer := Right.Reference.all'Length + 1;
  202.       Result : Unbounded_Wide_String :=
  203.                  (Reference => new Wide_String (1 .. Length));
  204.  
  205.    begin
  206.       Result.Reference.all (1)           := Left;
  207.       Result.Reference.all (2 .. Length) := Right.Reference.all;
  208.       return Result;
  209.    end "&";
  210.  
  211.    -----------
  212.    -- Count --
  213.    -----------
  214.  
  215.    function Count (Source   : in Unbounded_Wide_String;
  216.                    Pattern  : in Wide_String;
  217.                    Mapping  : in Wide_Maps.Wide_Character_Mapping
  218.                                 := Wide_Maps.Identity)
  219.    return Natural is
  220.    begin
  221.       return Wide_Search.Count (Source.Reference.all, Pattern, Mapping);
  222.    end Count;
  223.  
  224.    function Count (Source   : in Unbounded_Wide_String;
  225.                    Pattern  : in Wide_String;
  226.                    Mapping  : in Wide_Maps.Wide_Character_Mapping_Function)
  227.    return Natural is
  228.    begin
  229.       return Wide_Search.Count (Source.Reference.all, Pattern, Mapping);
  230.    end Count;
  231.  
  232.    function Count (Source   : in Unbounded_Wide_String;
  233.                    Set      : in Wide_Maps.Wide_Character_Set)
  234.    return Natural is
  235.    begin
  236.       return Wide_Search.Count (Source.Reference.all, Set);
  237.    end Count;
  238.  
  239.    ------------
  240.    -- Delete --
  241.    ------------
  242.  
  243.    function Delete (Source  : in Unbounded_Wide_String;
  244.                     From    : in Positive;
  245.                     Through : in Natural)
  246.      return Unbounded_Wide_String is
  247.  
  248.    begin
  249.       return
  250.         To_Unbounded_Wide_String
  251.           (Wide_Fixed.Delete (Source.Reference.all, From, Through));
  252.    end Delete;
  253.  
  254.    -------------
  255.    -- Element --
  256.    -------------
  257.  
  258.    function Element (Source : in Unbounded_Wide_String;
  259.                      Index  : in Positive)
  260.      return Wide_Character is
  261.  
  262.    begin
  263.       if Index <= Source.Reference.all'Last then
  264.          return Source.Reference.all (Index);
  265.       else
  266.          raise Strings.Index_Error;
  267.       end if;
  268.    end Element;
  269.  
  270.    ----------------
  271.    -- Find_Token --
  272.    ----------------
  273.  
  274.    procedure Find_Token (Source : in Unbounded_Wide_String;
  275.                          Set    : in Wide_Maps.Wide_Character_Set;
  276.                          Test   : in Strings.Membership;
  277.                          First  : out Positive;
  278.                          Last   : out Natural) is
  279.    begin
  280.       Wide_Search.Find_Token (Source.Reference.all, Set, Test, First, Last);
  281.    end Find_Token;
  282.  
  283.    ----------
  284.    -- Free --
  285.    ----------
  286.  
  287.    procedure Free (Handle : in out Unbounded_Wide_String) is
  288.       procedure Deallocate is
  289.          new Unchecked_Deallocation (Wide_String, Wide_String_Access);
  290.    begin
  291.       Deallocate (Handle.Reference);
  292.    end Free;
  293.  
  294.    ----------
  295.    -- Head --
  296.    ----------
  297.  
  298.    function Head (Source : in Unbounded_Wide_String;
  299.                   Count  : in Natural;
  300.                   Pad    : in Wide_Character := Blank)
  301.      return Unbounded_Wide_String is
  302.  
  303.    begin
  304.       return
  305.         To_Unbounded_Wide_String
  306.           (Wide_Fixed.Head (Source.Reference.all, Count, Pad));
  307.    end Head;
  308.  
  309.    -----------
  310.    -- Index --
  311.    -----------
  312.  
  313.    function Index (Source   : in Unbounded_Wide_String;
  314.                    Pattern  : in Wide_String;
  315.                    Going    : in Strings.Direction := Strings.Forward;
  316.                    Mapping  : in Wide_Maps.Wide_Character_Mapping :=
  317.                                    Wide_Maps.Identity)
  318.      return Natural is
  319.    begin
  320.       return Wide_Search.Index (Source.Reference.all, Pattern, Going, Mapping);
  321.    end Index;
  322.  
  323.    function Index (Source   : in Unbounded_Wide_String;
  324.                    Pattern  : in Wide_String;
  325.                    Going    : in Strings.Direction := Strings.Forward;
  326.                    Mapping  : in Wide_Maps.Wide_Character_Mapping_Function)
  327.      return Natural is
  328.    begin
  329.       return Wide_Search.Index (Source.Reference.all, Pattern, Going, Mapping);
  330.    end Index;
  331.  
  332.    function Index (Source : in Unbounded_Wide_String;
  333.                    Set    : in Wide_Maps.Wide_Character_Set;
  334.                    Test   : in Strings.Membership := Strings.Inside;
  335.                    Going  : in Strings.Direction  := Strings.Forward)
  336.      return Natural is
  337.  
  338.    begin
  339.       return Wide_Search.Index (Source.Reference.all, Set, Test, Going);
  340.    end Index;
  341.  
  342.    function Index_Non_Blank (Source : in Unbounded_Wide_String;
  343.                              Going  : in Strings.Direction := Strings.Forward)
  344.    return Natural is
  345.    begin
  346.       return Wide_Search.Index_Non_Blank (Source.Reference.all, Going);
  347.    end Index_Non_Blank;
  348.  
  349.    ------------
  350.    -- Insert --
  351.    ------------
  352.  
  353.    function Insert (Source   : in Unbounded_Wide_String;
  354.                     Before   : in Positive;
  355.                     New_Item : in Wide_String)
  356.      return Unbounded_Wide_String is
  357.  
  358.    begin
  359.       return
  360.         To_Unbounded_Wide_String
  361.           (Wide_Fixed.Insert (Source.Reference.all, Before, New_Item));
  362.    end Insert;
  363.  
  364.    ------------
  365.    -- Length --
  366.    ------------
  367.  
  368.    function Length (Source : in Unbounded_Wide_String) return Natural is
  369.    begin
  370.       return Source.Reference.all'Length;
  371.    end Length;
  372.  
  373.    ---------------
  374.    -- Overwrite --
  375.    ---------------
  376.  
  377.    function Overwrite (Source    : in Unbounded_Wide_String;
  378.                        Position  : in Positive;
  379.                        New_Item  : in Wide_String)
  380.      return Unbounded_Wide_String is
  381.  
  382.    begin
  383.       return To_Unbounded_Wide_String
  384.         (Wide_Fixed.Overwrite (Source.Reference.all, Position, New_Item));
  385.    end Overwrite;
  386.  
  387.    ---------------------
  388.    -- Replace_Element --
  389.    ---------------------
  390.  
  391.    procedure Replace_Element
  392.      (Source : in out Unbounded_Wide_String;
  393.       Index  : in Positive;
  394.       By     : in Wide_Character) is
  395.  
  396.    begin
  397.       if Index <= Source.Reference.all'Last then
  398.          Source.Reference.all (Index) := By;
  399.       else
  400.          raise Strings.Index_Error;
  401.       end if;
  402.    end Replace_Element;
  403.  
  404.    -------------------
  405.    -- Replace_Slice --
  406.    -------------------
  407.  
  408.    function Replace_Slice
  409.       (Source   : in Unbounded_Wide_String;
  410.        Low      : in Positive;
  411.        High     : in Natural;
  412.        By       : in Wide_String)
  413.      return Unbounded_Wide_String is
  414.    begin
  415.       return
  416.         To_Unbounded_Wide_String
  417.           (Wide_Fixed.Replace_Slice (Source.Reference.all, Low, High, By));
  418.    end Replace_Slice;
  419.  
  420.    -----------
  421.    -- Slice --
  422.    -----------
  423.  
  424.    function Slice (Source : in Unbounded_Wide_String;
  425.                    Low    : in Positive;
  426.                    High   : in Natural)
  427.      return Wide_String
  428.    is
  429.       Result : Wide_String (1 .. High - Low + 1);
  430.    begin
  431.       Result := Source.Reference.all (Low .. High);
  432.       return Result;
  433.    end Slice;
  434.  
  435.    ----------
  436.    -- Tail --
  437.    ----------
  438.  
  439.    function Tail (Source : in Unbounded_Wide_String;
  440.                   Count  : in Natural;
  441.                   Pad    : in Wide_Character := Blank)
  442.      return Unbounded_Wide_String is
  443.  
  444.    begin
  445.       return
  446.         To_Unbounded_Wide_String
  447.           (Wide_Fixed.Tail (Source.Reference.all, Count, Pad));
  448.    end Tail;
  449.  
  450.    --------------------
  451.    -- To_Wide_String --
  452.    --------------------
  453.  
  454.    function To_Wide_String (Source : in Unbounded_Wide_String)
  455.      return Wide_String is
  456.    begin
  457.       return Source.Reference.all;
  458.    end To_Wide_String;
  459.  
  460.    ------------------------------
  461.    -- To_Unbounded_Wide_String --
  462.    ------------------------------
  463.  
  464.    function To_Unbounded_Wide_String (Source : in Wide_String)
  465.      return Unbounded_Wide_String
  466.    is
  467.       Result : Unbounded_Wide_String;
  468.  
  469.    begin
  470.       Result := (Reference => new Wide_String (1 .. Source'Length));
  471.       Result.Reference.all := Source;
  472.       return Result;
  473.    end To_Unbounded_Wide_String;
  474.  
  475.    ---------------
  476.    -- Translate --
  477.    ---------------
  478.  
  479.    function Translate
  480.      (Source   : in Unbounded_Wide_String;
  481.       Mapping  : in Wide_Maps.Wide_Character_Mapping)
  482.      return Unbounded_Wide_String is
  483.  
  484.    begin
  485.       return
  486.         To_Unbounded_Wide_String
  487.           (Wide_Fixed.Translate (Source.Reference.all, Mapping));
  488.    end Translate;
  489.  
  490.    procedure Translate
  491.      (Source : in out Unbounded_Wide_String;
  492.       Mapping  : in Wide_Maps.Wide_Character_Mapping) is
  493.    begin
  494.       Wide_Fixed.Translate (Source.Reference.all, Mapping);
  495.    end Translate;
  496.  
  497.    function Translate
  498.      (Source   : in Unbounded_Wide_String;
  499.       Mapping  : in Wide_Maps.Wide_Character_Mapping_Function)
  500.      return Unbounded_Wide_String is
  501.  
  502.    begin
  503.       return
  504.         To_Unbounded_Wide_String
  505.           (Wide_Fixed.Translate (Source.Reference.all, Mapping));
  506.    end Translate;
  507.  
  508.    procedure Translate
  509.      (Source : in out Unbounded_Wide_String;
  510.       Mapping  : in Wide_Maps.Wide_Character_Mapping_Function) is
  511.    begin
  512.       Wide_Fixed.Translate (Source.Reference.all, Mapping);
  513.    end Translate;
  514.  
  515.    ----------
  516.    -- Trim --
  517.    ----------
  518.  
  519.    function Trim (Source : in Unbounded_Wide_String)
  520.      return Unbounded_Wide_String is
  521.    begin
  522.       return To_Unbounded_Wide_String (Wide_Fixed.Trim (Source.Reference.all));
  523.    end Trim;
  524.  
  525.    function Trim (Source : in Unbounded_Wide_String;
  526.                   Left   : in Wide_Maps.Wide_Character_Set;
  527.                   Right  : in Wide_Maps.Wide_Character_Set)
  528.      return Unbounded_Wide_String is
  529.  
  530.    begin
  531.       return
  532.         To_Unbounded_Wide_String
  533.           (Wide_Fixed.Trim (Source.Reference.all, Left, Right));
  534.    end Trim;
  535.  
  536. end Ada.Strings.Wide_Unbounded;
  537.